/*
 * @Author: Mr.Mao
 * @Date: 2021-06-23 21:35:13
 * @LastEditTime: 2021-06-23 23:34:03
 * @Description: 
 * @LastEditors: Mr.Mao
 * @autograph: 任何一个傻子都能写出让电脑能懂的代码，而只有好的程序员可以写出让人能看懂的代码
 */

import { TComplexType, VerifyType, TTypeConstructors } from "./types";
/**
 * @description 验证对应的数据是否是指定的类型
 * @param typeConstructor { TTypeConstructor }
 * @param value { any }
 */
export const validatorController = (typeConstructor?: TTypeConstructors | TTypeConstructors[], value?: any) => {
  // 如果是多例 一项通过即可
  if (Array.isArray(typeConstructor)) {
    let item: {
      type: string;
      status: boolean;
    };
    const result = typeConstructor.some(type => {
      item = validatorSingle(type, value)
      return item.status;
    })
    return {
      status: result,
      type: item.type
    }
  }
  // 如果是单例 进行单例验证即可
  return validatorSingle(typeConstructor, value)
}

/**
 * 单例验证
 * @param typeConstructor { TTypeConstructor }
 * @param value { any }
 */
const validatorSingle = (typeConstructor?: TTypeConstructors, value?: any) => {
  if (value === undefined || value === null) {
    return { type: 'undefined', status: true }
  }
  switch (typeConstructor) {
    case String: {
      return {
        status: typeof value === 'string',
        type: 'string'
      }
    }
    case Number: {
      return {
        status: typeof value === 'number',
        type: 'number'
      }
    }
    case Boolean: {
      return {
        status: typeof value === 'boolean',
        type: 'boolean'
      }
    }
    case Object: {
      return {
        status: value.constructor === Object,
        type: 'object'
      }
    }
    case Array: {
      return {
        status: Array.isArray(value),
        type: 'array'
      }
    }
    default: return { type: '', status: false }
  }
}

/**
 * @description 验证是否通过正则表达式
 * @param regExp { RegExp } 正则表达式
 * @param value { string } 验证的值
 * @return boolean { boolean } 是否通过验证
 */
export const regExpController = (value: string, regExp?: RegExp) => {
  if (!regExp || value === null || value === undefined) return true
  if (typeof value !== 'string') return false
  if (regExp.constructor !== RegExp) return false
  return regExp.test(value)
}
/** 校验配置 */
interface Option {
  key: string,
  value: any,
  complexVerify: TComplexType
}

/**
  * 处理校验項
  * @param key 当前校验 key 值
  * @param value 当前校验 value 值
  * @param complexVerify 当前校验规则
  */
export const checkVerifyItem = async ({ key, value, complexVerify }: Option) => {
  // 获取 Constructor 校验规则
  const ctrCheck = validatorController(complexVerify.type, value)
  // 创建校验器
  const validator = {
    paramType: ctrCheck.type,
    validType: 'none' as VerifyType,
    status: true
  }
  // 处理拦截校验
  if (complexVerify.intercept) {
    validator.validType = 'intercept'
    validator.status = typeof value === 'undefined'
    return validator
  }
  // 处理自定义校验器
  if (complexVerify.validator) {
    validator.validType = 'validator'
    try {
      const check = await complexVerify.validator(value)
      validator.status = check
    } catch (error) {
      validator.status = false
    }
    return validator
  }
  // 处理必传校验
  if (complexVerify.required) {
    validator.validType = 'required'
    validator.status = typeof value !== 'undefined'
    return validator
  }
  // 拦截未处理, 则 type 必传
  if (!complexVerify.type) {
    throw Error(`字段 ${key} 校验错误, type 未经过 intercept 拦截, type 为必传项.`)
  }
  // 处理类型校验
  if (!ctrCheck.status) {
    validator.validType = 'type'
    validator.status = ctrCheck.status
    return validator
  }
  // 处理正则校验
  if (complexVerify.regExp instanceof RegExp) {
    validator.validType = 'regExp'
    validator.status = regExpController(value, complexVerify.regExp)
    return validator
  }
  return validator
}
